module GYLite{
    export class GYGraphics extends egret.Graphics implements IBatch{        

        public x:number;
        public y:number;
        public width:number;
        public height:number;
        public constructor(target: egret.DisplayObject=null) {
            super();
            let s= this;            
            s.$renderNode = new egret.sys.GroupNode;            
            s._patternStyleMap = egret.createMap();
            s._color = [];
            s._alpha = [];
            s._ratio = [];
            s._fillColor = [];
            s._fillAlpha = [];
            s._fillRatio = [];            
            s._batchDrawParam = GraphicsTexture.batchParam;
            s._data = [];
            s._saves = [];
            s._lastCapNodes = [];
            // s._lastJointNodes = [];
            s._fillMatrix = new egret.Matrix;            
            s._gradientMatrix = new egret.Matrix;
            s._smoothing = true;
            s._isAllDraw = true;
            s.y = s.x = 0;
            s.width = s.height = 0;            
            s.$setTarget(target);            
            s._batch = true;
        }
          
        /**设置全局透明度*/
        public setGlobalAlpha(val:number):void
        {

        }        
        public clearBatch():void
		{
            let s = this;
            if(s._patternStyleMap)
            {
                let tex:GraphicsTexture;
                for(var key in s._patternStyleMap)			
				{
					tex = s._patternStyleMap[key];
					if(tex.disposed)										
						continue;					
					tex.$batchManager.removeDisplayBatch(s);
				}					
                s._patternStyleMap = egret.createMap();
            }            
		}
        /**合批图集名称*/
		public getBatchAtlasName():string{            
            let s= this;            
            if(s._batchAtlasName != null)
                return s._batchAtlasName;
            return (<any>this.$targetDisplay).getBatchAtlasName();
        }
        public setBatchAtlasName(val:string):void{            
            this._batchAtlasName = val;
        }
        
        /**合批绘制方式*/
        public getBatchDrawParam():BatchDrawParam{
            return this._batchDrawParam;
        }
        public setBatchDrawParam(val:BatchDrawParam):void{            
            this._batchDrawParam = val;
        }
        /**是否合批状态*/
        public isBatch():boolean{            
            return this._batch;
        }
        public enableBatch(val:boolean){            
            this._batch = val;
        }
        $setTarget(target: egret.DisplayObject): void {
            if (this.$targetDisplay) {
                this.$targetDisplay.$renderNode = null;
            }
            target.$renderNode = this.$renderNode;
            this.$targetDisplay = target;
            this.$targetIsSprite = target instanceof egret.Sprite;
        }
        protected setStrokeWidth(width: number) {
            switch (width) {
                case 1:
                    this.topLeftStrokeWidth = 0;
                    this.bottomRightStrokeWidth = 1;
                    break;
                case 3:
                    this.topLeftStrokeWidth = 1;
                    this.bottomRightStrokeWidth = 2;
                    break;
                default:
                    let half = Math.ceil(width * 0.5) | 0;
                    this.topLeftStrokeWidth = half;
                    this.bottomRightStrokeWidth = half;
                    break;
            }
        }
        /**开始填充
         * @param color 颜色
         * @param alpha 透明度
        */
        public beginFill(color: number, alpha: number = 1): void {
            color = +color || 0;
            alpha = +alpha || 0;            
            let s= this;
            color = color|0;
            s._fillGradientType = null;            
            s._fillColor.length = 0;
            s._fillColor[0] = color;
            s._fillAlpha.length = 0;
            s._fillAlpha[0] = alpha;
            s._fillRatio.length = 0;
            s._fillTexture = null;
            s._fillMatrix.identity();
            s._gradientMatrix.identity();
        }
        /**渐变填充*/
        public beginGradientFill(type: string, colors: number[], alphas: number[], ratios: number[], matrix: egret.Matrix = null): void {
            
            let s= this;
            s._fillGradientType = type;
            if(colors && colors.length > 0)
                s._fillColor = colors.concat();
            else
            {
                s._fillColor.length = 0;
                s._fillColor[0] = 0;
            }                
            if(alphas && alphas.length > 0)
                s._fillAlpha = alphas.concat();
            else
            {
                s._fillAlpha.length = 0;
                s._fillAlpha[0] = 1;
            }
            if(ratios && ratios.length > 0)
                s._fillRatio = ratios.concat();
            else
            {
                s._fillRatio.length = 0;
                s._fillRatio = [1,1];
            }
            if(matrix)
                s._gradientMatrix.copyFrom(matrix);                  
        }
        /**位图填充*/
        public beginBitmapFill(tex:egret.Texture, matrix:egret.Matrix,repeat:boolean=false,alpha:number=1):void
        {
            let s= this;
            s._fillGradientType = null;
            s._fillColor.length = 0;
            s._fillRatio.length = 0;
            s._fillTexture = tex;
            s._fillRepeat = repeat;  
            s._fillAlpha.length = 0;
            s._fillAlpha[0] = alpha;          
            if(matrix)            
                s._fillMatrix.copyFrom(matrix);            
            else            
                s._fillMatrix.identity();
        }
        /**闭合填充*/
        public endFill(): void {
            
            let s= this;            
            s._fillAlpha.length = 0;
            s._fillColor.length = 0;
            s._fillRatio.length = 0;
            s._fillTexture = null;
        }
        /**笔触样式
         * @param thickness 笔触大小，默认1
         * @param color 颜色，默认0
         * @param alpha 透明度，默认1
         * @param pixelHinting 是否完整像素 默认false（此功能暂时未提供）
         * @param scaleMode 拉伸模式 默认"normal"，此功能暂时未提供
         * @param cap 端点 默认"round"
         * @param joint 拐角 默认null，此功能暂时未提供
         * @param miterLimit 拐角最大像素,仅在joint为"miter"有效，默认0，此功能暂时未提供
         * @param lineDash 虚线值，默认[6,3]，此功能暂时未提供
         * @param tex 纹理填充
         * @param matrix 纹理的变换
        */
        public lineStyle(thickness: number = 1, color: number = 0, alpha: number = 1.0, pixelHinting: boolean = false,
            scaleMode: string = "normal", cap: string = "round", joint: string = "round", miterLimit: number = 3, lineDash: number[]=null): void {
            thickness = +thickness || 0;
            color = +color || 0;
            alpha = +alpha || 1.0;
            miterLimit = +miterLimit || 0;
            let s= this;
            s._miterLimit = miterLimit;
            s._color.length = 0;
            s._ratio.length = 0;
            s._alpha.length = 0;            
            s._lineGradientType = null;
            s.newLine();
            s._texture = null;
            s._color[0] = color|0;            
            s._alpha[0] = alpha;
            s._thickness = Math.round(thickness);
            s._cap = <any>cap;
            s._joint = <any>joint;
            
            if (thickness <= 0) {
                s.strokePath = null;
                s.setStrokeWidth(0);
            }
            else {
                s.setStrokeWidth(thickness);                
            }
        }   
        /**位图填充笔触
         * @param thickness 笔触大小
         * @param alpha 透明度
         * @param tex 填充的纹理
         * @param matrix 纹理的矩阵变换，默认null，则纹理垂直于线条方向
         * */    
        public lineBitmapStyle(thickness: number = 1, alpha:number=1, tex:egret.Texture=null,matrix:egret.Matrix=null):void
        {
            thickness = +thickness || 1;            
            alpha = +alpha || 1.0;
            let s= this;
            s._color.length = 0;
            s._ratio.length = 0;
            s._alpha.length = 0;   
            s._lineGradientType = null;
            s.newLine();    
            if(tex)
            {
                s._texture = tex;
                if(matrix)
                {
                    if(s._lineMatrix)
                        s._lineMatrix.copyFrom(matrix)
                    else
                        s._lineMatrix = matrix.clone();
                }                    
                else
                    s._lineMatrix = null;
            }
            else                
                s._color[0] = 0;            
            s._alpha[0] = alpha;
            s._thickness = thickness;
            
            if (thickness <= 0) {
                s.strokePath = null;
                s.setStrokeWidth(0);
            }
            else {
                s.setStrokeWidth(thickness);                
            }
        }
        /**渐变填充笔触*/
        public lineGradientStyle(thickness: number = 1, type: string, colors: number[], alphas: number[], ratios: number[], matrix: egret.Matrix = null,cap:CanvasLineCap=null,joint:CanvasLineJoin=null):void
        {
            let s= this;       
            thickness = +thickness || 1;
            s._texture = null;     
            s.newLine();
            s._lineGradientType = type;
            if(colors && colors.length > 0)
                s._color = colors.concat();
            else
            {
                s._color.length = 0;
                s._color[0] = 0;
            }                
            if(alphas && alphas.length > 0)
                s._alpha = alphas.concat();
            else
            {
                s._alpha.length = 0;
                s._alpha[0] = 1;
            }
            if(ratios && ratios.length > 0)
                s._ratio = ratios.concat();
            else
            {
                s._ratio.length = 0;
                s._ratio = [1,1];
            }
            s._thickness = thickness;
            s._cap = cap?cap:"round";
            s._joint = joint?joint:"round";
            if(matrix)
                s._gradientMatrix.copyFrom(matrix);
            if (thickness <= 0) {
                s.strokePath = null;
                s.setStrokeWidth(0);
            }
            else {
                s.setStrokeWidth(thickness);                
            }
        }
        /**dataDraw-矩形绘制*/
        public drawRect(x: number, y: number, width: number, height: number): void {
            x = +x || 0;
            y = +y || 0;
            width = +width || 0;
            height = +height || 0;
            if(width < 1 || height < 1)
                return;
            
            let vertices:number[] = [];
            vertices = [x,y,x + width,y,x + width,y + height,x,y + height];

            let s= this;
            let d:GraphicsData;
            d = new GraphicsData(x, y,GraphicsType.RECT);
            d.inputGraphics(s);
            d.width = width;
            d.height = height;
            d.vertices = vertices;            
            s.addData(d);            
            
            if(s.$targetDisplay.stage)
            {
                s.doDrawPoly(vertices, false);
                d.isDraw = true;
            }                
        }        
        /**dataDraw-圆角矩形绘制*/
        public drawRoundRect(x: number, y: number, width: number, height: number, ellipseWidth: number, ellipseHeight: number=NaN): void {
            x = +x || 0;
            y = +y || 0;
            width = +width || 0;
            height = +height || 0;
            ellipseWidth = +ellipseWidth || 0;
            ellipseHeight = ellipseHeight == ellipseHeight?ellipseHeight:ellipseWidth;                        
            if(width < 1 || height < 1)return;

            let s= this;
            let r:number,b:number,xlw:number,xrw:number,ytw:number,ybw:number; 
            let xx:number,yy:number;
            let rx:number,ry:number;            
            let vertices:number[];

            ellipseWidth = Math.min((width - 2)/2,ellipseWidth);
            ellipseHeight = Math.min((height - 2)/2,ellipseHeight);


            rx = ellipseWidth;
            ry = ellipseHeight;
            xx = x;
            yy = y;
            
            r = xx + width;
            b = yy + height;
            xlw = xx + rx;
            xrw = r - rx;
            ytw = yy + ry;
            ybw = b - ry;

            if(ellipseWidth > 3 || ellipseHeight > 3)
            {
                vertices = [];
                s.arcToBezier(xrw,ybw,rx,ry,0,Math.PI/2,false,0.04,true,vertices);
                s.arcToBezier(xlw,ybw,rx,ry,Math.PI/2,Math.PI,false,0.04,true,vertices);
                s.arcToBezier(xlw,ytw,rx,ry,Math.PI,Math.PI*1.5,false,0.04,true,vertices);            
                s.arcToBezier(xrw,ytw,rx,ry,Math.PI*1.5,MathConst.DOUBLE_PI,false,0.04,true,vertices);
            }            
            
            let d:CircleData;
            d = new CircleData(x, y,GraphicsType.ROUNDRECT);
            d.inputGraphics(s);
            d.density = s._densty;
            d.width = width;
            d.height = height;                                
            d.radiusX = ellipseWidth;
            d.radiusY = ellipseHeight?ellipseHeight:ellipseWidth;
            d.vertices = vertices;
            s.addData(d);

            if(s.$targetDisplay.stage)
            {
                s.doDrawPoly(vertices);
                d.isDraw = true;
            }
        }
        
        /**dataDraw-圆绘制*/
        public drawCircle(x: number, y: number, radius: number,density:number=NaN,smoothing:boolean=true): void {
            x = +x || 0;
            y = +y || 0;
            radius = +radius || 0;
            if(radius < 1)
                return;
            
            let s= this; 
            let d:CircleData;
            d = new CircleData(x, y,GraphicsType.CIRCLE);
            d.inputGraphics(s);
            d.radiusX = radius;
            d.radiusY = radius;
            d.density = density;      
            d.smoothing = smoothing;
            s.addData(d);
            
            if(s.$targetDisplay.stage)
            {
                s.doDrawCircle(x,y,radius,radius,density,smoothing);
                d.isDraw = true;
            }
            
        }
        /**do-执行圆绘制（包含椭圆）*/
        private doDrawCircle(x:number,y:number,radiusX:number,radiusY:number,density:number=NaN,smoothing:boolean=true):void
        {
            let s= this;
            let tex:GraphicsTexture;
            let element:GraphicsElement;            
            let bTex:egret.Texture;
            let batchInfo:BatchInfo; 
            let type:GraphicsType;
            let noFill:boolean;
            let arr:number[];                        
            if(s._fillTexture)
            {
                arr=[];
                s.arcToBezier(x,y,radiusX,radiusY,0,MathConst.DOUBLE_PI,false,density,false,arr);
                s.doDrawPoly(arr, false);  
            }
            else if(s._fillColor && s._fillColor.length > 0)
            {
                type = radiusX < 16?GraphicsType.CIRCLE:GraphicsType.RECT;
                batchInfo = s.getBatch({
                    // color:s._fillColor,
                    alpha:s._fillAlpha,                                
                    radiusX:radiusX,
                    radiusY:radiusY                
                }, type);
                tex = <GraphicsTexture>batchInfo.$sourceTexture;
                bTex = batchInfo?batchInfo.$batchTexture:tex;
                element = <GraphicsElement>tex.element;
                        
                if(type == GraphicsType.CIRCLE)
                {//圆形纹理
                    let bNode:GYBitmapNode;                    
                    bNode = s.createBitmapNode(bTex,null,s._fillGradientType?null:s._fillColor[0]);                                
                    bNode.setOffset(-element.$originX - radiusX,-element.$originY - radiusY);
                    bNode.translate(x,y);
                    bNode.setAlpha(s._fillAlpha.length > 0?s._fillAlpha[0]:1);
                    s.addNode(bNode);                                 
                    bNode.setRect(x - radiusX, x + radiusX, y - radiusY, y + radiusY);
                }
                else
                {//方形纹理                    
                    arr = [];                    
                    //圆采样
                    s.arcToBezier(x,y,radiusX,radiusY,0,MathConst.DOUBLE_PI,false,density,false,arr);                    
                    s.doDrawPoly(arr,false,false);
                    //平滑补偿
                    if(smoothing && s._fillGradientType == null)
                    {
                        s.save();                        
                        s.doMoveTo(arr[2], arr[3]);
                        s._alpha = [s._fillAlpha[0]];
                        s._color = [s._fillColor[0]];
                        s._thickness = 1;
                        s._cap = null;
                        s.arcToBezier(x,y,radiusX,radiusY,0,MathConst.DOUBLE_PI);
                        s.restore();
                    }
                    
                }
                //描边
                if(s._color && s._color.length > 0)
                {
                    s.save();                    
                    s.arcToBezier(x,y,radiusX+s._thickness,radiusY+s._thickness,0,MathConst.DOUBLE_PI,false,density);
                    s.restore();
                } 
            }
            else
                noFill = true;            
            if(noFill)
                return;
            
            //-1 +2 解决WebGL裁切问题
            s.extendBoundsByPoint(x - radiusX - 1, y - radiusY - 1);
            s.extendBoundsByPoint(x + radiusX + 2, y + radiusY + 2);
            s.updatePosition(x, y);
            s.dirty();
        }
        /**dataDraw-椭圆绘制*/
        public drawEllipse(x: number, y: number, width: number, height: number, density:number=NaN,smoothing:boolean=true): void {
            x = +x || 0;
            y = +y || 0;
            width = +width || 0;
            height = +height || 0;
            if(width < 1 || height < 1)
                return;
    
            let radiusX:number,radiusY:number;
            let s = this; 
            radiusX = width >> 1;
            radiusY = height >> 1;

            let d:CircleData;
            d = new CircleData(x, y,GraphicsType.ELLIPSE);
            d.inputGraphics(s);
            d.radiusX = radiusX;
            d.radiusY = radiusY;
            d.density = density;      
            d.smoothing = smoothing;
            s.addData(d);
            
            if(s.$targetDisplay.stage)
            {
                s.doDrawCircle(x,y,radiusX,radiusY,density,smoothing);
                d.isDraw = true;
            }            
        }
        /**dataDraw-绘制多边形*/
        public drawPoly(path:number[]): void
        {
            let s= this;
            let d:PolyData;
            if(path == null || path.length == 0)
                return;
            d = new PolyData(0, 0, GraphicsType.POLY);
            d.inputGraphics(s);
            d.vertices = path.concat();
            s.addData(d);

            if(s.$targetDisplay.stage)
            {
                s.doDrawPoly(path);
                d.isDraw = true;
            }             
        }
        /**do-执行绘制多边形
         * @param path 多边形路径
         * @param check 检测多边形顶点是否交错 默认true
         * @param stroke 描边 默认true         
        */
        private doDrawPoly(path:number[],check:boolean=true,stroke:boolean=true):GYMeshNode
        {
            let result:SeparatorResult;
            let s= this;
            let vertices:number[],indices:number[],uvs:number[];            

            let tex:GraphicsTexture;
            let element:GraphicsElement;            
            let bTex:egret.Texture;
            let batchInfo:BatchInfo;
            let noFill:boolean;
            
            let gNode:GYMeshNode;
            let u:number,v:number;
            let w:number,h:number;
            let sclX:number,sclY:number;
            let padX:number,padY:number;
            let whDis:number;
            let i:number,len:number;
            let x:number,y:number;
            let param:any;       
            if(path == null || path.length == 0)
                return null;
                     
            if(s._fillColor && s._fillColor.length > 0)
            {
                result = Separator.separate(path, check);                
                if(result.error)
                {
                    console.error(result.error.msg);
                    return null;
                }
                w = result.width;
                h = result.height;
                vertices = result.vertices;
                indices = result.indices;
                param = {
                    // color:s._fillColor,
                    alpha:s._fillAlpha.length > 0?s._fillAlpha[0]:1
                };                
                if(s._fillGradientType)
                {
                    param = s.createGradientParam(param,s._fillRatio,w,h);                   
                    param.gradientType = s._fillGradientType;                                    
                    param.gradientMatrix = s._gradientMatrix;
                    whDis = Math.abs(result.width - result.height);
                    param.color = s._fillColor;
                }

                batchInfo = s.getBatch(param,GraphicsType.RECT);
                tex = <GraphicsTexture>batchInfo.$sourceTexture;
                bTex = batchInfo?batchInfo.$batchTexture:tex;
                element = <GraphicsElement>tex.element;

                gNode = s.createMeshNode(bTex, s._fillGradientType?NaN:s._fillColor[0]);
                gNode.indices = indices;
                gNode.alpha = s._fillAlpha.length > 0?s._fillAlpha[0]:1;

                padX = (0.5+element.$originX - element.blurSizeX)*2;
                padY = (0.5+element.$originY - element.blurSizeY)*2;
                sclX = (bTex.$bitmapWidth - padX) / bTex.$bitmapWidth;
                sclY = (bTex.$bitmapHeight - padY) / bTex.$bitmapHeight;
                len = vertices.length;
                for(i=0;i<len;i+=2)
                {                    
                    x = vertices[i];
                    y = vertices[i+1];                      
                    
                    if(s._fillGradientType == GradientType.RADIAL.name)
                    {
                        if(result.width > result.height)
                        {
                            u = (x - result.left)/w * sclX + (1-sclX)/2;
                            v = (y - result.top + whDis/2)/(h + whDis) * sclY + (1-sclY)/2;
                        }
                        else
                        {
                            u = (x - result.left + whDis/2)/(w + whDis) * sclX + (1-sclX)/2;
                            v = (y - result.top)/h * sclY + (1-sclY)/2;
                        }                        
                    }
                    else
                    {
                        u = (x - result.left)/w * sclX + (1-sclX)/2;
                        v = (y - result.top)/h * sclY + (1-sclY)/2;
                    }                    
                    gNode.addVertex(x,y,u,v);
                }
                gNode.setRect(result.left,result.right,result.top,result.bottom);                
            }
            else if(s._fillTexture)
            {                        
                result = Separator.separate(path, check,true,0,0,s._fillTexture.$bitmapWidth,s._fillTexture.$bitmapHeight, s._fillMatrix,s._fillRepeat);
                if(result.error)
                {
                    console.error(result.error.msg);
                    return null;
                }
                w = result.width;
                h = result.height;
                vertices = result.vertices;
                indices = result.indices;
                uvs = result.uvs;
                bTex = s.getBatchTexture(s._fillTexture);
                gNode = s.createTexMeshNode(bTex,vertices,uvs,indices);
                gNode.alpha = s._fillAlpha.length > 0?s._fillAlpha[0]:1;
                gNode.setRect(result.left,result.right,result.top,result.bottom);
            }
            else
                noFill = true;            

            if(noFill)
                return null;
                            
            gNode.drawMesh(bTex.$bitmapX,bTex.$bitmapY,bTex.$bitmapWidth,bTex.$bitmapHeight,0,0,result.width,result.height);
            s.addNode(gNode);            

            // 描边
            if(s._color && s._color.length > 0 && stroke && s._thickness > 0)
            {   
                len = path.length;
                if(len > 0)
                {                    
                    s.save();
                    gNode = null;
                    for(i=0;i<len;i+=2)
                    {                    
                        x = path[i];
                        y = path[i+1];
                        if(i == 0)
                            s.doMoveTo(x,y);
                        else
                            gNode = s.dolineTo(x,y,0,gNode,s._cap,s._cap,s._joint);
                    }
                    s.dolineTo(path[0],path[1],0,gNode);
                    s.restore();
                }
            }

            s.extendBoundsByPoint(result.right, result.bottom);
            s.updatePosition(result.left, result.top);
            s.dirty();
            return gNode;
        }
        /**dataDraw-绘制三角形
         * @param vertices 顶点坐标 例如 [10,10,30,10,30,30]
         * @param uvs uv贴图坐标，例如 [0,0,1,0,1,1]
         * @param indices 顶点索引，例如 [0,1,2]
        */
        public drawTriangle(vertices:number[],uvs:number[],indices:number[]):void
        {
            let s = this;            
            let d:TriangleData;
            if(uvs == null)
                uvs = [0,0,1,0,1,1];
            if(indices == null)
                indices = [0,1,2];
            if(vertices.length != 6 || uvs.length != 6 || indices.length != 3)
                return;
            d = new TriangleData(0, 0, GraphicsType.POLY);
            d.vertices = vertices.concat();
            d.uvs = uvs.concat();
            d.indices = indices.concat();            
            s.addData(d);

            if(s.$targetDisplay.stage)
            {
                s.doDrawTriangle(d.vertices,d.uvs,d.indices);
                d.isDraw = true;
            }
        }
        private doDrawTriangle(vertices:number[],uvs:number[]=null,indices:number[]=null):void
        {
            let s= this;
            let tex:GraphicsTexture;
            let element:GraphicsElement;            
            let bTex:egret.Texture;
            let batchInfo:BatchInfo;
            let noFill:boolean;                        
            let gNode:GYMeshNode;            
            
            let i:number,len:number;
            let x:number,y:number;             
            let r:number,b:number,l:number,t:number;
            let w:number,h:number,width:number,height:number;
            l = t = Number.MAX_VALUE;
            r = b = Number.MIN_VALUE;   
            if(uvs == null)
                uvs = [0,0,1,0,1,1];
            if(indices == null)
                indices = [0,1,2];
            len = vertices.length;
            for(i=0;i<len;i+=2)
            { 
                x = vertices[i];
                y = vertices[i+1];
                if(l > x)
                    l = x;
                if(r < x)
                    r = x;
                if(t > y)
                    t = y;
                if(b < y)
                    b = y;
            }
            width = r - l;
            height = b - t;
            
            if(s._fillColor && s._fillColor.length > 0)
            {
                let sclX:number,sclY:number;
                let padX:number,padY:number;
                let whDis:number;
                let param:any;
                let u:number,v:number;
                param = {
                    // color:s._fillColor,
                    alpha:s._fillAlpha.length > 0?s._fillAlpha[0]:1
                };                
                if(s._fillGradientType)
                {
                    param = s.createGradientParam(param,s._fillRatio,width,height);                    
                    param.gradientType = s._fillGradientType;                                    
                    param.gradientMatrix = s._gradientMatrix;
                    whDis = Math.abs(width - height);
                    param.color = s._color;
                }
                batchInfo = s.getBatch(param,GraphicsType.RECT);
                tex = <GraphicsTexture>batchInfo.$sourceTexture;
                bTex = batchInfo?batchInfo.$batchTexture:tex;
                element = <GraphicsElement>tex.element;                
                w = element.width;
                h = element.height;

                gNode = s.createMeshNode(bTex, s._fillGradientType?NaN:s._fillColor[0]);
                gNode.indices = indices;
                gNode.alpha = s._fillAlpha.length > 0?s._fillAlpha[0]:1;
                gNode.setRect(l,r,t,b);

                padX = (0.5+element.$originX - element.blurSizeX)*2;
                padY = (0.5+element.$originY - element.blurSizeY)*2;
                sclX = (bTex.$bitmapWidth - padX) / bTex.$bitmapWidth;
                sclY = (bTex.$bitmapHeight - padY) / bTex.$bitmapHeight;
                len = vertices.length;
                for(i=0;i<len;i+=2)
                {                    
                    x = vertices[i];
                    y = vertices[i+1];                      
                    
                    if(s._fillGradientType == GradientType.RADIAL.name)
                    {
                        if(width > height)
                        {
                            u = (x - l)/width * sclX + (1-sclX)/2;
                            v = (y - t + whDis/2)/(height + whDis) * sclY + (1-sclY)/2;
                        }
                        else
                        {
                            u = (x - l + whDis/2)/(width + whDis) * sclX + (1-sclX)/2;
                            v = (y - t)/height * sclY + (1-sclY)/2;
                        }                        
                    }
                    else
                    {
                        u = (x - l)/width * sclX + (1-sclX)/2;
                        v = (y - t)/height * sclY + (1-sclY)/2;
                    }                    
                    gNode.addVertex(x,y,u,v);
                }                
            }
            else if(s._fillTexture)
            {
                bTex = s.getBatchTexture(s._fillTexture);
                gNode = s.createTexMeshNode(bTex,vertices,uvs,indices);
                gNode.alpha = s._fillAlpha.length > 0?s._fillAlpha[0]:1;
                gNode.setRect(l,r,t,b);
            }
            else
                noFill = true;            

            if(noFill)
                return;
                 
            gNode.drawMesh(bTex.$bitmapX,bTex.$bitmapY,bTex.$bitmapWidth,bTex.$bitmapHeight,0,0,w,h);
            s.addNode(gNode);

            // 描边
            if(s._color && s._color.length > 0 && s._thickness > 0)
            {   
                len = vertices.length;
                if(len > 0)
                {
                    s.save();
                    gNode = null;
                    for(i=0;i<len;i+=2)
                    {                    
                        x = vertices[i];
                        y = vertices[i+1];
                        if(i == 0)
                            s.doMoveTo(x,y);
                        else
                            gNode = s.dolineTo(x,y,0,gNode,s._cap,s._cap,s._joint);
                    }
                    s.dolineTo(vertices[0],vertices[1],0,gNode);
                    s.restore();
                }
            }
            s.extendBoundsByPoint(r, b);
            s.updatePosition(l,t);
            s.dirty();
        }
        /**笔触移动到(x,y)*/
        public moveTo(x: number, y: number): void {
            let s= this;
            x = +x || 0;
            y = +y || 0;
            
            s.newLine();
            s.includeLastPosition = false;
            s.doMoveTo(x,y);
        }
        private doMoveTo(x:number,y:number):void
        {
            let s= this;
            s._lastStartX = s.lastX;
            s._lastStartY = s.lastY;
            s.lastX = x;
            s.lastY = y;
            s.dirty();
        }
        /**dataDraw-从当前笔触位置绘制线段到(x,y)*/
        public lineTo(x: number, y: number): void {
            let s = this;
            x = +x || 0;
            y = +y || 0;            
            
            let lastX:number,lastY:number;
            lastX = s.lastX;
            lastY = s.lastY;

            let d:LineData;
            if(s._lastLineData == null || s.lastData.type != GraphicsType.LINE)
            {                
                d = new LineData(lastX, lastY,GraphicsType.LINE);
                d.inputGraphics(s);                
                d.vertices = [lastX,lastY,x,y];       
                s._lastLineData = d;         
                s.addData(d);
            }
            else
            {
                d = (<LineData>s.lastData);
                d.vertices.push(x,y);
            }
                
            if(s.$targetDisplay.stage)
            {
                s._lastLineNode = s.dolineTo(x,y,0,s._lastLineNode,s._cap,s._cap,s._joint);
                d.isDraw = true;
            }
            
        }
        /**执行绘制线段
         * @param x 目标坐标x
         * @param y 目标坐标y
         * @param blur 如果未产生锯齿，默认使用的模糊像素，默认0，不使用
         * @param lastLineNode 上一个线段节点
         * @param cap 端点 默认null，无端点
         * @param joint 拐角 默认null，无拐角
         * @param dataLine 是否graphics绘制数据，默认false
        */
        private dolineTo(x: number, y: number,blur:number=0,lastLineNode:GYMeshNode,capStart:CanvasLineCap=null,capEnd:CanvasLineCap=null,joint: CanvasLineJoin = null):GYMeshNode
        {
            let s = this;
            let tex:GraphicsTexture;
            let element:GraphicsElement;            
            let bTex:egret.Texture;
            let batchInfo:BatchInfo;            
            let blurSize:number,angle:number;
            let dx:number,dy:number,dx2:number,dy2:number;
            let lastX:number,lastY:number;
            let type:GraphicsType;

            let w:number,h:number;                
            let mNode:GYMeshNode;
            let midY1:number,midY2:number;
            let lineLength:number;         
            let i:number,len:number;       
            let m:egret.Matrix;
            let tx:number,ty:number;
            let vtNum:number;
            let hasLastCap:boolean;
            let rect:GYLite.Scale9GridRect;
            let param:any;
            let vertices:number[],uvs:number[],indices:number[];
            
            if(!(s._thickness > 0))
                return;

            lastX = s.lastX;
            lastY = s.lastY;
            
            type = GraphicsType.LINE;            
            angle = MathUtil.calAngle(lastX,lastY,x,y);
            dx = x - lastX;
            dy = y - lastY;
            if(dx<0)dx=-dx;
            if(dy<0)dy=-dy;                
            if(dx > 0 && dy > 0)
                blurSize = 1;
            else
                blurSize = blur;
            if(s._color && s._color.length > 0)
            {
                param = {
                    // color:s._color,                        
                    lineWidth:s._thickness,     
                    blurSize:blurSize
                };                
                if(s._lineGradientType)
                {
                    if(s._ratio.length > 0)
                    {
                        const minSize = 8;
                        if(s._lineGradientType == GradientType.LINEAR.name)
                            param.scaleSizeX = s._ratio.length*minSize;
                        else
                            param.scaleSizeX = s._ratio.length*Math.max(minSize,minSize*Math.min(dx,s._thickness)/100);                            
                        param.ratio = s._ratio;
                        param.alpha = s._alpha.length > 0?s._alpha[0]:1;
                    }
                    param.gradientType = s._lineGradientType;                                    
                    param.gradientMatrix = s._gradientMatrix;
                    param.color = s._color;                    
                }
                batchInfo = s.getBatch(param,GraphicsType.LINE);
                // if(batchInfo == null)//test
                // {
                //     debugger;
                //     s.getBatch(param,GraphicsType.LINE);
                    
                // }
                
                tex = <GraphicsTexture>batchInfo.$sourceTexture;
                bTex = batchInfo?batchInfo.$batchTexture:tex;
                element = <GraphicsElement>tex.element;
                rect = element.getScaleRect(GraphicsType.LINE);
                
                w = element.width;
                h = element.height;
                lineLength = Math.pow(dx*dx+dy*dy,0.5);
                midY1 = s._thickness + element.blurSizeY;
                if(midY1 % 2 == 0)
                    midY2 = midY1 = midY1/2;
                else
                {
                    midY1 = midY1 >> 1;
                    midY2 = midY1 + 1;
                }
                m = GYLite.GYSprite._matrix;
                m.identity();
                m.rotate(angle);
                // if(lastLineNode)
                // {
                //     mNode = lastLineNode;                        
                // }                        
                // else
                // {
                    mNode = s.createMeshNode(bTex, s._lineGradientType?NaN:s._color[0]);                    
                    mNode.alpha = s._alpha.length > 0?s._alpha[0]:1;
                    mNode.drawMesh(bTex.$bitmapX,bTex.$bitmapY,bTex.$bitmapWidth,bTex.$bitmapHeight,x,y,w,h);                        
                    s.addNode(mNode);                        
                // }
                vtNum = (mNode.vertices.length/2);
                indices = mNode.indices;
                vertices = mNode.vertices;
                uvs = mNode.uvs;

                indices.push(vtNum,vtNum+1,vtNum+2,vtNum,vtNum+2,vtNum+3);
                vertices.push(          
                    0, -midY1,                                       
                    0 + lineLength, -midY1,
                    0 + lineLength, 0 + midY2,
                    0, 0 + midY2
                );                  
                uvs.push(rect.leftGap/w,rect.topGap/h,       
                (w - rect.rightGap)/w,rect.topGap/h,
                (w - rect.rightGap)/w,(h - rect.bottomGap)/h,                    
                rect.leftGap/w,(h - rect.bottomGap)/h);
                
                len = vertices.length;                
                for(i=len - 8;i<len;i+=2)             
                {
                    tx = vertices[i];
                    ty = vertices[i+1];
                    vertices[i] = m.a * tx + m.c * ty + lastX;
                    vertices[i+1] = m.d * ty + m.b * tx + lastY;
                }                
                hasLastCap = s._lastCapNodes.length > 0;
                if(lastLineNode && joint)
                {
                    if(hasLastCap)
                    {
                        if(capStart != "round")
                            s.removeNodes(s._lastCapNodes);                    
                        s._lastCapNodes.length = 0;
                    }
                    if(capStart != "round")//圆形直接用下个线段起点端点做拐角
                        s.jointDraw(lastX,lastY,x,y,mNode.vertices,s._thickness,element);                        
                    s.capDraw(lastX,lastY,x,y,mNode.vertices,s._thickness,angle,midY1,capStart == "round"?capStart:null,capEnd,blurSize,element);                                       
                }                    
                else if(capStart)
                {
                    s.capDraw(lastX,lastY,x,y,mNode.vertices,s._thickness,angle,midY1,capStart,capEnd,blurSize,element);
                }
                    
                mNode.updatePosBound(lastX,lastY);
                mNode.updatePosBound(x,y);
            }
            else if(s._texture)
            {                    
                lineLength = Math.pow(dx*dx+dy*dy,0.5);
                midY1 = s._thickness;
                if(midY1 % 2 == 0)
                    midY2 = midY1 = midY1/2;
                else
                {
                    midY1 = midY1 >> 1;
                    midY2 = midY1 + 1;
                }
                vertices = [];
                vertices.push(          
                    0, -midY1,                                       
                    0 + lineLength, -midY1,
                    0 + lineLength, 0 + midY2,
                    0, 0 + midY2
                );  
                m = GYLite.GYSprite._matrix;
                m.identity();
                m.rotate(angle);
                
                len = vertices.length;                
                for(i=len - 8;i<len;i+=2)             
                {
                    tx = vertices[i];
                    ty = vertices[i+1];
                    vertices[i] = m.a * tx + m.c * ty + lastX;
                    vertices[i+1] = m.d * ty + m.b * tx + lastY;
                }

                let result:SeparatorResult;
                if(s._lineMatrix == null)
                {
                    m = GYGraphics._tempMatrix;
                    m.identity();
                    m.rotate(angle);                        
                    m.translate(lastX+Math.sin(angle)*midY1,lastY-Math.cos(angle)*midY1);
                }
                else
                    m = s._lineMatrix;                        
                result = Separator.separate(vertices, false,true,s._texture.$offsetX,s._texture.$offsetY,s._texture.$bitmapWidth,s._texture.$bitmapHeight, m, true);
                if(result.error)
                {
                    console.error(result.error.msg);
                    return;
                }
                w = result.width;
                h = result.height;
                vertices = result.vertices;
                indices = result.indices;
                uvs = result.uvs;
                bTex = s.getBatchTexture(s._texture);                
                
                // if(lastLineNode)
                // {
                //     mNode = lastLineNode;
                //     mNode.vertices = mNode.vertices.concat(vertices);
                //     mNode.indices = mNode.vertices.concat(indices);
                //     mNode.uvs = mNode.vertices.concat(uvs);
                // }
                // else
                // {
                    mNode = s.createTexMeshNode(bTex,vertices,uvs,indices);                        
                    mNode.alpha = s._alpha.length > 0?s._alpha[0]:1;                        
                    mNode.drawMesh(bTex.$bitmapX,bTex.$bitmapY,bTex.$bitmapWidth,bTex.$bitmapHeight,0,0,result.width,result.height);
                    s.addNode(mNode);                        
                // }    
                mNode.setRect(result.left,result.right,result.top,result.bottom);
            }
            
            this.updatePosition(x, y);
            this.dirty();  
            return mNode;          
        }
        private jointDraw(lastX:number,lastY:number,x:number,y:number,vertices:number[],thickness:number,element:GraphicsElement):void
        {
            let s= this;            
            let wise:number;
            let jointX1:number,jointX2:number,jointY1:number,jointY2:number,jointX3:number,jointY3:number,jointX4:number,jointY4:number;                        
            let jointStX1:number,jointStX2:number,jointStY1:number,jointStY2:number;
            if(thickness <= 2)
                return;       
            let agl:number;
            agl = MathUtil.calVecAngle(s._lastStartX - lastX,s._lastStartY - lastY,x - lastX,y - lastY);            
            wise = PositionUtil.clockwise(s._lastStartX,s._lastStartY,lastX,lastY,x,y);
            if(Math.abs(wise) < 50 || agl < Math.PI/30)//拐角小于一定程度或者夹角面积小于一定程度，直接连接，不需要画
            {
                vertices[vertices.length-8] = vertices[vertices.length - 14];
                vertices[vertices.length-7] = vertices[vertices.length - 13];
                vertices[vertices.length-2] = vertices[vertices.length - 12];
                vertices[vertices.length-1] = vertices[vertices.length - 11];
                return;
            }
            if(wise!=0)
            {
                if(wise > 0)
                {                    
                    jointX1 = vertices[vertices.length-8];
                    jointY1 = vertices[vertices.length-7];
                    jointStX1 = vertices[vertices.length - 6];
                    jointStY1 = vertices[vertices.length - 5];
                    jointX2 = vertices[vertices.length - 14];
                    jointY2 = vertices[vertices.length - 13];
                    jointStX2 = vertices[vertices.length - 16];
                    jointStY2 = vertices[vertices.length - 15];
                }                            
                else if(wise < 0)
                {                    
                    jointX1 = vertices[vertices.length-12];
                    jointY1 = vertices[vertices.length-11];
                    jointStX1 = vertices[vertices.length - 10];
                    jointStY1 = vertices[vertices.length - 9];
                    jointX2 = vertices[vertices.length - 2];
                    jointY2 = vertices[vertices.length - 1];
                    jointStX2 = vertices[vertices.length - 4];
                    jointStY2 = vertices[vertices.length - 3];
                }
                let jointAngle:number;
                let cp:egret.Point;
                s.save();
                s._fillGradientType = null;
                s._fillColor.length = 0;
                s._fillColor[0] = s._lineGradientType?element.endColor:s.color[0];
                s._fillAlpha.length = 0;
                s._fillAlpha[0] = s.alpha[0];
                jointAngle = MathUtil.calAngle(jointStX1,jointStY1,jointX1,jointY1);
                jointX3 = jointX1 + Math.cos(jointAngle) * s._miterLimit;
                jointY3 = jointY1 + Math.sin(jointAngle) * s._miterLimit;
                jointAngle = MathUtil.calAngle(jointStX2,jointStY2,jointX2,jointY2);
                jointX4 = jointX2 + Math.cos(jointAngle) * s._miterLimit;
                jointY4 = jointY2 + Math.sin(jointAngle) * s._miterLimit;
                if(PositionUtil.clockwise(jointX3,jointY3,jointX1,jointY1,jointX4,jointY4) > 0)
                {
                    s.doDrawPoly([jointX1,jointY1,lastX,lastY,jointX2,jointY2,jointX4,jointY4,jointX3,jointY3],false,false);                                
                }
                else
                {
                    cp = MathUtil.calCrossPoint(jointStX1,jointStY1,jointX1,jointY1,jointStX2,jointStY2,jointX2,jointY2,GYGraphics._tempPt0);
                    if(cp)
                    {
                        jointX3 = cp.x;
                        jointY3 = cp.y;                                    
                        s.doDrawPoly([jointX1,jointY1,lastX,lastY,jointX2,jointY2,jointX3,jointY3],false,false);                        
                    }
                }                            
                s.restore();
            } 
        }
        private capDraw(lastX:number,lastY:number,x:number,y:number,vertices:number[],thickness:number,agl:number,midY1:number,capStart:CanvasLineCap=null,capEnd:CanvasLineCap=null,blur:number=1,element:GraphicsElement=null):void
        {
            let s= this;                        
            let rx:number,ry:number,r:number,tBlur:number,stColor:number,stAlpha:number,endColor:number,endAlpha:number;            
            let i:number,len:number,j:number,len2:number;
            let toX:number,toY:number;
            let sin:number,cos:number;            
            let is_half_PI:boolean;
            let meshNode:GYMeshNode;
            let cap:string;
            let verticesStar:number[],verticesEnd:number[];

            s.save();
            s._lineGradientType = null;
            GYGraphics._lineCaps.length = 0;
            GYGraphics._lineCaps.push(capStart,capEnd);            
            stColor = s._color[0];
            endColor = s._color[s._color.length - 1];
            stAlpha = s._alpha[0];
            endAlpha = s._alpha[s._alpha.length - 1];
            cos = Math.cos(agl);
            sin = Math.sin(agl);            
            if(stColor != endColor && element)
            {
                stColor = element.startColor;
                endColor = element.endColor;
            }
            len2 = 2;
            for(j=0;j<len2;++j)
            {
                cap = GYGraphics._lineCaps[j];                
                if(cap == "square")
                {   
                    verticesStar = verticesEnd = vertices;    
                    rx = thickness*0.6 - 1;
                    rx = Math.max(1,rx);
                    ry = rx;
                    
                    if(j == 0)
                    {
                        //起始端点
                        s._color = [stColor];
                        s._alpha = [stAlpha];                        
                        toX = lastX - cos*rx;
                        toY = lastY - sin*ry;
                        s.doMoveTo(toX,toY);
                        meshNode = s.dolineTo(lastX,lastY,blur,null);
                        meshNode.vertices[2] = verticesStar[vertices.length - 8];
                        meshNode.vertices[3] = verticesStar[vertices.length - 7];
                        meshNode.vertices[4] = verticesStar[vertices.length - 2];
                        meshNode.vertices[5] = verticesStar[vertices.length - 1];
                        verticesStar = meshNode.vertices;
                    }
                    else if(j == 1)
                    {
                        //终止端点
                        s._color = [endColor];
                        s._alpha = [endAlpha];                        
                        toX = x + cos*rx;
                        toY = y + sin*ry;
                        s.doMoveTo(x,y);
                        meshNode = s.dolineTo(toX,toY,blur,null);
                        meshNode.vertices[0] = verticesEnd[vertices.length - 6];
                        meshNode.vertices[1] = verticesEnd[vertices.length - 5];
                        meshNode.vertices[6] = verticesEnd[vertices.length - 4];
                        meshNode.vertices[7] = verticesEnd[vertices.length - 3];
                        verticesEnd = meshNode.vertices;
                        s._lastCapNodes.push(meshNode);                        
                    }     
                }
                else if(cap)
                {
                    verticesStar = verticesEnd = vertices;                    
                    len = midY1;
                    is_half_PI = agl%MathConst.HALF_PI == 0;                    
                    if(j == 0)
                    {
                        s._color = [stColor];
                        s._alpha = [stAlpha];  
                        for(i = is_half_PI?0:1;i<len;++i)
                        {
                            tBlur = (i == 0 && thickness > 3)?blur:1;
                            r = i + (is_half_PI?1:0);
                            ry = rx = Math.sqrt(midY1*midY1 - i*i)*2|0;                                                                               
                            s._thickness = is_half_PI?rx + (thickness%2==0?0:1):rx - 1;                            
                            //起始端点                            
                            toX = lastX - cos * r;
                            toY = lastY - sin * r;
                            s.doMoveTo(toX,toY);
                            meshNode = s.dolineTo(lastX,lastY,tBlur,null);
                            meshNode.vertices[2] = verticesStar[verticesStar.length - 8];
                            meshNode.vertices[3] = verticesStar[verticesStar.length - 7];
                            meshNode.vertices[4] = verticesStar[verticesStar.length - 2];
                            meshNode.vertices[5] = verticesStar[verticesStar.length - 1];                         
                            verticesStar = meshNode.vertices;                            
                        }
                    }
                    else if(j == 1)
                    {
                        s._color = [endColor];
                        s._alpha = [endAlpha];
                        for(i = is_half_PI?0:1;i<len;++i)
                        {
                            tBlur = (i == 0 && thickness > 3)?blur:1;
                            r = i + (is_half_PI?1:0);
                            ry = rx = Math.sqrt(midY1*midY1 - i*i)*2|0;                                                                            
                            s._thickness = is_half_PI?rx + (thickness%2==0?0:1):rx - 1;                            
                            //终止端点                                        
                            toX = x + cos * r;
                            toY = y + sin * r;
                            s.doMoveTo(x,y);
                            meshNode = s.dolineTo(toX,toY,tBlur,null);
                            meshNode.vertices[0] = verticesEnd[verticesEnd.length - 6];
                            meshNode.vertices[1] = verticesEnd[verticesEnd.length - 5];
                            meshNode.vertices[6] = verticesEnd[verticesEnd.length - 4];
                            meshNode.vertices[7] = verticesEnd[verticesEnd.length - 3];
                            verticesEnd = meshNode.vertices;
                            s._lastCapNodes.push(meshNode);                                                                                 
                        }
                    }                    
                }                
            }                        
            s.restore();            
        }
        private pathDraw(result:number[]):GYMeshNode[]
        {
            let s= this;
            let i:number,len:number;
            let nodes:GYMeshNode[];
            let node:GYMeshNode;
            nodes = [];
            len = result.length;
            for(i=0;i<len;i+=2)
            {
                if(i==0)
                    s.doMoveTo(result[i],result[i+1]);
                else
                    node = s.dolineTo(result[i],result[i+1],0,node);
                if(node != nodes[nodes.length - 1])
                    nodes.push(node);
            }            
            return nodes;
        }
        private bezierDraw(x:number,y:number,end:number):void
        {
            let s= this;            
            if(end == 0)
                s.doMoveTo(x,y);
            else
            {
                s._lastBezierNode = s.dolineTo(x,y,1,s._lastBezierNode,s._lastBezierNode?null:s._cap,end == 2?s._cap:null,s._joint);
            }                
        }
        /**dataDraw-从当前坐标开始绘制二次贝塞尔曲线*/
        public curveTo(controlX: number, controlY: number, anchorX: number, anchorY: number): void {
            controlX = +controlX || 0;
            controlY = +controlY || 0;
            anchorX = +anchorX || 0;
            anchorY = +anchorY || 0;
            
            let s= this;
            let lastX = s.lastX || 0;
            let lastY = s.lastY || 0;
            let d:LineData;
            d = new LineData(lastX, lastY,GraphicsType.CURVE);
            d.inputGraphics(s);            
            d.vertices = [lastX,lastY,controlX,controlY,anchorX,anchorY];
            d.thickness = s._thickness;            
            s.addData(d);

            if(s.$targetDisplay.stage)
            {
                s.doCubicCurve(lastX,lastY,controlX,controlY,controlX,controlY,anchorX,anchorY);
                d.isDraw = true;
            }            
            s.moveTo(anchorX,anchorY);
        }        
        /**dataDraw-从当前坐标开始绘制三次贝塞尔曲线*/
        public cubicCurveTo(controlX1: number, controlY1: number, controlX2: number,
            controlY2: number, anchorX: number, anchorY: number): void {
            controlX1 = +controlX1 || 0;
            controlY1 = +controlY1 || 0;
            controlX2 = +controlX2 || 0;
            controlY2 = +controlY2 || 0;
            anchorX = +anchorX || 0;
            anchorY = +anchorY || 0;
            
            let s =this;
            let lastX = s.lastX || 0;
            let lastY = s.lastY || 0;
            let d:LineData;
            d = new LineData(lastX, lastY,GraphicsType.CUBIC_CURVE);
            d.inputGraphics(s);
            d.vertices = [lastX,lastY,controlX1,controlY1,controlX2,controlY2,anchorX,anchorY];
            d.thickness = s._thickness;            
            s.addData(d);

            if(s.$targetDisplay.stage)
            {
                s.doCubicCurve(lastX,lastY,controlX1,controlY1,controlX2,controlY2,anchorX,anchorY);
                d.isDraw = true;
            }            
            s.moveTo(anchorX,anchorY);
        }
        private doCubicCurve(lastX:number,lastY:number,controlX:number,controlY:number,controlX2:number,controlY2:number,anchorX:number,anchorY:number):void
        {
            let s= this;
            GYGraphics._tempPt0.setTo(lastX,lastY);
            GYGraphics._tempPt1.setTo(controlX,controlY);
            GYGraphics._tempPt2.setTo(controlX2,controlY2);
            GYGraphics._tempPt3.setTo(anchorX,anchorY);     
            s.save();       
            GYLite.BezierPoint.drawThreeTimesCall(GYGraphics._tempPt0,GYGraphics._tempPt1,GYGraphics._tempPt2,GYGraphics._tempPt3,s._densty,s.bezierDraw,s);
            s._lastBezierNode = null;
            s.restore();
            s.extendBoundsByPoint(anchorX, anchorY);
            s.updatePosition(anchorX, anchorY);
            s.dirty();            
        }
        public drawArc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean,density:number=NaN): void 
        {
            x = +x || 0;
            y = +y || 0;
            radius = +radius || 50;
            startAngle = +startAngle || 0;
            endAngle = +endAngle || MathConst.DOUBLE_PI;
            anticlockwise = !!anticlockwise;
            startAngle = MathUtil.clampAngle(startAngle);
            endAngle = MathUtil.clampAngle(endAngle);
            if(endAngle == startAngle)
            {
                startAngle = 0;
                endAngle = MathConst.DOUBLE_PI;
            }
            if (anticlockwise) {
                if (endAngle >= startAngle) {
                    endAngle -= Math.PI * 2;
                }
            }
            else {
                if (endAngle <= startAngle) {
                    endAngle += Math.PI * 2;
                }
            }

            let s= this;
            let d:ArcData;
            d = new ArcData(s.lastX, s.lastY,GraphicsType.ARC);
            d.inputGraphics(s);                        
            d.thickness = s._thickness;        
            d.startAngle = startAngle;
            d.endAngle = endAngle;
            d.radius = radius;    
            s.addData(d);

            if(s.$targetDisplay.stage)
            {                
                s.doDrawArc(x,y,radius,startAngle,endAngle,anticlockwise,density);
                d.isDraw = true;
            }            
        }
        /**do-执行绘制一段圆弧
         * @param x 圆心x
         * @param y 圆心y
         * @param radius 圆弧半径
         * @param startAngle 起始弧度
         * @param endAngle 结束弧度
         * @param anticlockwise 是否逆时针 默认false
        */
        protected doDrawArc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean,density:number=NaN): void {
            if (radius < 0 || startAngle === endAngle) {
                return;
            }
            let s= this;
            s.save();       
            s.arcToBezier(x,y,radius,radius,startAngle,endAngle,anticlockwise);
            s.restore();

            if (anticlockwise) {
                s.arcBounds(x, y, radius, endAngle, startAngle);
            }
            else {
                s.arcBounds(x, y, radius, startAngle, endAngle);
            }
            let endX = x + Math.cos(endAngle) * radius;
            let endY = y + Math.sin(endAngle) * radius;
            s.updatePosition(endX, endY);
            s.dirty();
        }
        /**使用贝塞尔曲线画一段圆弧线
         * @param x 圆心x
         * @param y 圆心y
         * @param radiusX 横向半径
         * @param radiusY 纵向半径
         * @param startAngle 起始弧度
         * @param endAngle 结束弧度
         * @param anticlockwise 是否逆时针 默认false
         * @param density 采样密度 默认0.04
         * @param excludeEndPoint 是否忽略最后一个端点 默认false
         * @param result 采样结果数组 默认null，则直接绘制，否则result里存放采样的坐标
        */
        private arcToBezier(x:number,y:number,radiusX:number,radiusY:number,startAngle:number,endAngle:number,anticlockwise:boolean=false,density:number=0.04, excludeEndPoint:boolean=false,result:number[]=null):void
        {
            let s =this;
            let lastX = s.lastX || 0;
            let lastY = s.lastY || 0;
            var halfPI = Math.PI * 0.5;
            var start = startAngle;
            var end = start;
            var draw:boolean;
            draw = result == null;
            if(draw)
                result = [];
            if (anticlockwise) {
                end += -halfPI - (start % halfPI);
                if (end < endAngle) {
                    end = endAngle;
                }
            }
            else {
                end += halfPI - (start % halfPI);
                if (end > endAngle) {
                    end = endAngle;
                }
            }
            density = density == density?density:s._densty
            let currentX = x + Math.cos(start) * radiusX;
            let currentY = y + Math.sin(start) * radiusY;            
            if (lastX != currentX || lastY != currentY) {
                s.doMoveTo(currentX, currentY);
            }
            let addAngle:number,a:number,x1:number,y1:number,x2:number,y2:number;
            let u = Math.cos(start);
            let v = Math.sin(start);
            GYGraphics._tempPt0.setTo(currentX,currentY);
            for (let i:number = 0; i < 4; i++) {
                addAngle = end - start;
                a = 4 * Math.tan(addAngle / 4) / 3;
                x1 = currentX - v * a * radiusX;
                y1 = currentY + u * a * radiusY;
                u = Math.cos(end);
                v = Math.sin(end);
                currentX = x + u * radiusX;
                currentY = y + v * radiusY;
                x2 = currentX + v * a * radiusX;
                y2 = currentY - u * a * radiusY;                
                GYGraphics._tempPt1.setTo(x1,y1);
                GYGraphics._tempPt2.setTo(x2,y2);
                GYGraphics._tempPt3.setTo(currentX,currentY);                                
                BezierPoint.drawThreeTimesCall(GYGraphics._tempPt0,GYGraphics._tempPt1,GYGraphics._tempPt2,GYGraphics._tempPt3,density,function(x:number,y:number,end:number):void{
                    if(!excludeEndPoint || end != 2)
                        result.push(x,y);
                },s);
                GYGraphics._tempPt0.setTo(currentX,currentY);
                if (end === endAngle) {
                    break;
                }
                start = end;
                if (anticlockwise) {
                    end = start - halfPI;
                    if (end < endAngle) {
                        end = endAngle;
                    }
                }
                else {
                    end = start + halfPI;
                    if (end > endAngle) {
                        end = endAngle;
                    }
                }
            }
            if(draw)
                s.pathDraw(result);
        }        
    
        protected dirty(): void {
            let s = this;                          
            const target = s.$targetDisplay;
            target.$cacheDirty = true;
            let p = target.$parent;
            if (p && !p.$cacheDirty) {
                p.$cacheDirty = true;
                p.$cacheDirtyUp();
            }
            let maskedObject = target.$maskedObject;
            if (maskedObject && !maskedObject.$cacheDirty) {
                maskedObject.$cacheDirty = true;
                maskedObject.$cacheDirtyUp();
            }
        }
    
        protected arcBounds(x: number, y: number, radius: number, startAngle: number, endAngle: number): void {
            let PI = Math.PI;
            if (Math.abs(startAngle - endAngle) < 0.01) {
                this.extendBoundsByPoint(x - radius, y - radius);
                this.extendBoundsByPoint(x + radius, y + radius);
                return;
            }
            if (startAngle > endAngle) {
                endAngle += PI * 2;
            }
            let startX = Math.cos(startAngle) * radius;
            let endX = Math.cos(endAngle) * radius;
            let xMin = Math.min(startX, endX);
            let xMax = Math.max(startX, endX);
    
            let startY = Math.sin(startAngle) * radius;
            let endY = Math.sin(endAngle) * radius;
            let yMin = Math.min(startY, endY);
            let yMax = Math.max(startY, endY);
    
            let startRange = startAngle / (PI * 0.5);
            let endRange = endAngle / (PI * 0.5);
            for (let i = Math.ceil(startRange); i <= endRange; i++) {
                switch (i % 4) {
                    case 0:
                        xMax = radius;
                        break;
                    case 1:
                        yMax = radius;
                        break;
                    case 2:
                        xMin = -radius;
                        break;
                    case 3:
                        yMin = -radius;
                        break;
                }
            }
            xMin = Math.floor(xMin);
            yMin = Math.floor(yMin);
            xMax = Math.ceil(xMax);
            yMax = Math.ceil(yMax);
            this.extendBoundsByPoint(xMin + x, yMin + y);
            this.extendBoundsByPoint(xMax + x, yMax + y);
        }
    
        public clear(): void {            
            let s= this;
            s.clearBatch();
            s._isAllDraw = true;
            s._fillGradientType = null;
            s._lineGradientType = null;
            s._lastLineNode= null;
            s._lastCapNodes.length = 0;
            s._fillAlpha.length = 0;
            s._fillColor.length = 0;
            s._fillRatio.length = 0;
            s._fillTexture = null;
            s._fillRepeat = false;
            
            s._color.length = 0;
            s._alpha.length = 0;
            s._ratio.length = 0;
            s._texture = null;
            s._data.length = 0;
            s._fillMatrix.identity();
            s._gradientMatrix.identity();
            s.includeLastPosition = false;
            s._saves.length = 0;
            let node:egret.sys.GroupNode;
            node = <egret.sys.GroupNode>this.$renderNode;                
            node.drawData.length = 0;
            s._cacheDrawData = null;
            s.updatePosition(0, 0);
            s.minX = Infinity;
            s.minY = Infinity;
            s.maxX = -Infinity;
            s.maxY = -Infinity;
            s.dirty();
        }
        protected extendBoundsByPoint(x: number, y: number): void {
            let s= this;
            s.extendBoundsByX(x);
            s.extendBoundsByY(y);
        }
    
        protected extendBoundsByX(x: number): void {
            let s= this;
            s.minX = Math.min(s.minX, x - s.topLeftStrokeWidth);
            s.maxX = Math.max(s.maxX, x + s.bottomRightStrokeWidth);
            s.updateNodeBounds();
        }
    
        protected extendBoundsByY(y: number): void {
            let s= this;
            s.minY = Math.min(s.minY, y - s.topLeftStrokeWidth);
            s.maxY = Math.max(s.maxY, y + s.bottomRightStrokeWidth);
            s.updateNodeBounds();
        }
    
        protected updateNodeBounds(): void {
            let s = this;
            s.x = this.minX;
            s.y = this.minY;
            s.width = Math.ceil(this.maxX - this.minX);
            s.height = Math.ceil(this.maxY - this.minY);         
        }
        protected updatePosition(x: number, y: number): void {
            let s =this;
            if (!s.includeLastPosition) {
                s.extendBoundsByPoint(s.lastX, s.lastY);
                s.includeLastPosition = true;
            }
            s._lastStartX = s.lastX;
            s._lastStartY = s.lastY;
            s.lastX = x;
            s.lastY = y;
            s.extendBoundsByPoint(x, y);
        }
    
        $measureContentBounds(bounds: egret.Rectangle): void {
            if (this.minX === Infinity) {
                bounds.setEmpty();
            }
            else {
                bounds.setTo(this.minX, this.minY, this.maxX - this.minX, this.maxY - this.minY);
            }
        }
    
        $hitTest(stageX: number, stageY: number): egret.DisplayObject {
            let s = this;            
            let x:number,y:number;
            let i:number,len:number,j:number,len2:number;
            let arr:egret.sys.RenderNode[];
            let ax:number,ay:number,bx:number,by:number,cx:number,cy:number;
            let w1:number,w2:number,w3:number,ind:number;
            let bmpNode:GYBitmapNode,meshNode:GYMeshNode;            
            s.$targetDisplay.globalToLocal(stageX,stageY,GYLite.GYSprite._pt);
            x = GYLite.GYSprite._pt.x;
            y = GYLite.GYSprite._pt.y;
            arr = s.$renderNode.drawData;
            len = arr.length;
            for(i=0;i<len;++i)
            {                
                if(arr[i].constructor == GYBitmapNode)
                {//位图节点只用于16像素以下的圆，所以采取只判断矩形框的策略
                    bmpNode = <GYBitmapNode>arr[i];
                    if(bmpNode.left < x && bmpNode.right > x && bmpNode.top < y && bmpNode.bottom > y)                    
                        return s.$targetDisplay;                    
                }
                else
                {//mesh节点先判断矩形框，再遍历三角形判断
                    meshNode = <GYMeshNode>arr[i];
                    if(meshNode.left < x && meshNode.right > x && meshNode.top < y && meshNode.bottom > y)                    
                    {
                        len2 = meshNode.indices.length;
                        for(j=0;j<len2;j+=3)
                        { 
                            ind = meshNode.indices[j]*2;
                            ax = meshNode.vertices[ind];
                            ay = meshNode.vertices[ind + 1];
                            ind = meshNode.indices[j + 1]*2;
                            bx = meshNode.vertices[ind];
                            by = meshNode.vertices[ind + 1];
                            ind = meshNode.indices[j + 2]*2;
                            cx = meshNode.vertices[ind];
                            cy = meshNode.vertices[ind + 1];
                            w1 = PositionUtil.clockwise(ax,ay,bx,by,x,y);
                            w2 = PositionUtil.clockwise(bx,by,cx,cy,x,y);
                            w3 = PositionUtil.clockwise(cx,cy,ax,ay,x,y);
                            if(w1 >= 0 && w2 >= 0 && w3 >= 0 || w1 <= 0 && w2 <= 0 && w3 <= 0)
                            {                                
                                return s.$targetDisplay;
                            }                                
                        }                            
                    }                    
                }
            }                      
            return null;
        }
        
        public $onAddToStage(){
            let s= this;            
            s._batchAtlasName = (<any>this.$targetDisplay).getBatchAtlasName();
            if(s._batchAtlasName == null)
                s._batchAtlasName = AtlasRender.defaultAtlasName;
            if(s._cacheDrawData)
            {
                s.$renderNode.drawData = s._cacheDrawData;
                s._cacheDrawData = null;
            }
            //绘制未
            if(!s._isAllDraw)
            {
                let i:number,len:number;
                len = s._data.length;
                for(i=0;i<len;++i)
                {
                    s.drawData(s._data[i]);
                }
                s._isAllDraw = true;
            }
        }
        $onRemoveFromStage(): void {
            let s = this;
            if (s.$renderNode) {//此处缓存节点数组，直接清理GroupNode的节点
                s._cacheDrawData = s.$renderNode.drawData;
                s.$renderNode.drawData = [];
            }
        }

        /**获取合批对象*/
        public getBatch(param:any,type:GraphicsType):BatchInfo
        {
            let s= this;
            let tex:GraphicsTexture;
            let batchInfo:BatchInfo;
            
            tex = GraphicsTexture.getGraphicsTexture(param, type);            
            batchInfo = AtlasRender.getInstance().addBatch(tex,s);            
            if(batchInfo)
                batchInfo.measureAndDraw();
            s._patternStyleMap[tex.hash] = tex;
            return batchInfo;
        }
        public get lastData():GraphicsData
        {
            let s = this;
            return s._data[s._data.length - 1];
        }        
        private createBitmapNode(bTex:egret.Texture,rect:Scale9GridRect=null,color:number=NaN):GYBitmapNode
        {
            let s= this;
            let gNode:GYBitmapNode;            
            gNode = new GYBitmapNode(bTex,rect);
            gNode.image = bTex.$bitmapData;
            gNode.imageWidth = bTex.$sourceWidth;
            gNode.imageHeight = bTex.$sourceHeight;            
            gNode.smoothing = s._smoothing;
            if(color == color)            
                gNode.color = ColorUtil.revertColor(color);            
            return gNode;
        }
        private createMeshNode(bTex:egret.Texture,color:number=NaN):GYMeshNode
        {
            let s= this;
            let gNode:GYMeshNode;            
            gNode = new GYMeshNode;
            gNode.image = bTex.$bitmapData;
            gNode.imageWidth = bTex.$sourceWidth;
            gNode.imageHeight = bTex.$sourceHeight;            
            gNode.smoothing = s._smoothing;
            if(color == color)            
                gNode.color = ColorUtil.revertColor(color);
            return gNode;
        }
        private createTexMeshNode(fTex:egret.Texture, vertices:number[],uvs:number[],indices:number[]):GYMeshNode
        {            
            let gNode:GYMeshNode;            
            let s = this;
            gNode = s.createMeshNode(fTex);
            gNode.vertices = vertices;
            gNode.uvs = uvs;
            gNode.indices = indices;
            return gNode;
        }
        private newLine():void
        {
            let s= this;                        
            s._lastCapNodes.length = 0;            
            s._lastLineNode = s._lastLineData = null;
        }
        
        private _saves:any[];
        private save():void
        {
            let s= this;
            let obj:any;
            obj = {};
            obj.saveX = s.lastX;
            obj.saveY = s.lastY;
            obj.saveStartX = s._lastStartX;
            obj.saveStartY = s._lastStartY;
            obj.saveAlpha = s._alpha.concat();
            obj.saveColor = s._color.concat();
            obj.saveRatio = s._ratio.concat();
            obj.saveLineMatrix = s._lineMatrix?s._lineMatrix.clone():null;
            obj.saveLineGradientType = s._lineGradientType;
            obj.saveFillAlpha = s._fillAlpha.concat();
            obj.saveFillColor = s._fillColor.concat();
            obj.saveFillRatio = s._fillRatio.concat();
            obj.saveFillMatrix = s._fillMatrix.clone();
            obj.saveFillGradientType = s._fillGradientType;
            obj.saveThickness = s._thickness;            
            obj.saveLineCap = s._cap;   
            obj.saveLineJoint = s._joint;
            obj.saveMiterLimit = s._miterLimit;
            s._saves.push(obj);
        }
        private restore():void
        {
            let s = this;
            let obj:any;
            if(s._saves.length == 0)return;
            obj = s._saves.pop();
            s.lastX = obj.saveX;
            s.lastY = obj.saveY;
            s._lastStartX = obj.saveStartX;
            s._lastStartY = obj.saveStartY;
            s._alpha = obj.saveAlpha;
            s._color = obj.saveColor;
            s._ratio = obj.saveRatio;
            s._lineMatrix = obj.lineMatrix;
            s._fillAlpha = obj.saveFillAlpha;
            s._fillColor = obj.saveFillColor;
            s._fillMatrix = obj.saveFillMatrix;
            s._fillRatio = obj.saveFillRatio;
            s._thickness = obj.saveThickness;
            s._cap = obj.saveLineCap;
            s._joint = obj.saveLineJoint;
            s._miterLimit = obj.saveMiterLimit;
            s._lineGradientType = obj.saveLineGradientType;
            s._fillGradientType = obj.saveFillGradientType;
        }
        protected drawData(d:GraphicsData):void
        {
            if(d.isDraw)
                return;
            let s= this;
            let circleData:CircleData,triangleData:TriangleData;

            if(d.texture)            
                s.lineBitmapStyle(d.thickness,d.alpha[0],d.texture,d.matrix);            
            else if(d.ratio && d.ratio.length > 1)
                s.lineGradientStyle(d.thickness,d.lineGradientType,d.color,d.alpha,d.ratio,d.matrix);
            else if(d.color && d.color.length > 0)            
                s.lineStyle(d.thickness,d.color[0],d.alpha[0],false,"normal",d.cap,d.joint,d.miterLimit);

            if(d.fillTexture)
                s.beginBitmapFill(d.fillTexture,d.fillMatrix,d.fillRepeat,d.fillAlpha[0]);
            else if(d.fillRatio && d.fillRatio.length > 0)
                s.beginGradientFill(d.fillGradientType,d.fillColor,d.fillAlpha,d.fillRatio,d.fillMatrix);
            else if(d.fillColor && d.fillColor.length > 0)
                s.beginFill(d.fillColor[0],d.fillAlpha[0])

            if(d.type == GraphicsType.RECT)
            {
                s.doDrawPoly(d.vertices, false);
            }
            else if(d.type == GraphicsType.ROUNDRECT)
            {
                s.doDrawPoly(d.vertices);
            }
            else if(d.type == GraphicsType.CIRCLE || d.type == GraphicsType.ELLIPSE)
            {
                circleData = (<CircleData>d);
                s.doDrawCircle(circleData.x,circleData.y,circleData.radiusX,circleData.radiusX,circleData.density,circleData.smoothing);
            }            
            else if(d.type == GraphicsType.TRIANGLE)
            {
                triangleData = (<TriangleData>d);
                s.doDrawTriangle(triangleData.vertices,triangleData.uvs,triangleData.indices);
            }
            else if(d.type == GraphicsType.POLY)
            {
                s.doDrawPoly(d.vertices,true,true)
            }
            else if(d.type == GraphicsType.LINE)
            {
                let i:number,len:number;       
                let lineData:LineData;         
                let node:GYMeshNode;
                lineData = <LineData>d;
                len = lineData.vertices.length;
                for(i=0;i<len;i+=2)
                {
                    if(i==0)
                        s.doMoveTo(lineData.vertices[i],lineData.vertices[i+1]);
                    else
                    {
                        s._lastLineNode = node = s.dolineTo(lineData.vertices[i],lineData.vertices[i+1],0,node,lineData.cap,lineData.cap,lineData.joint);                    
                    }
                        
                }
            }
            else if(d.type == GraphicsType.CURVE)
            {
                s.doCubicCurve(d.vertices[0],d.vertices[1],d.vertices[2],d.vertices[3],d.vertices[2],d.vertices[3],d.vertices[4],d.vertices[5]);
            }
            else if(d.type == GraphicsType.CUBIC_CURVE)
            {
                s.doCubicCurve(d.vertices[0],d.vertices[1],d.vertices[2],d.vertices[3],d.vertices[4],d.vertices[5],d.vertices[6],d.vertices[7]);
            }
            else if(d.type == GraphicsType.ARC)
            {
                let arcData:ArcData;
                arcData = (<ArcData>d);
                s.doDrawArc(arcData.x,arcData.y,arcData.radius,arcData.startAngle,arcData.endAngle,arcData.anticlockwise,arcData.density);
            }
            d.isDraw = true;
        }

        protected removeNodes(nodes:egret.sys.RenderNode[]):void
        {
            let len:number;
            let s= this;
            len = nodes.length;
            while(--len>-1)
            {
                s.removeNode(nodes[len]);
            }
        }       
        protected removeNode(node:egret.sys.RenderNode):void
        {
            let s= this;
            let len:number;
            let renderNode:egret.sys.GroupNode;
            renderNode = (<egret.sys.GroupNode>s.$renderNode);
            len = renderNode.drawData.length;
            while(--len>-1)
            {
                if(renderNode.drawData[len] == node)
                {
                    renderNode.drawData.splice(len,1);
                    break;
                }
            }
        }
        protected addData(d:GraphicsData):void
        {
            let s= this;
            s._data.push(d);
            s._isAllDraw = false;
        }
        protected addNode(node:egret.sys.RenderNode):void
        {
            let s= this;
            (<egret.sys.GroupNode>s.$renderNode).addNode(node);
        }
        protected createGradientParam(param:any,ratio:number[],w:number,h:number):any
        {
            let s =this;
            if(ratio.length > 0)
            {
                const minSize = 8;
                let size:number;
                if(s._fillGradientType == GradientType.LINEAR.name)
                    param.scaleSizeX = ratio.length*minSize;
                else
                {
                    size = Math.max(minSize,minSize*Math.min(w,h)/100);                            
                    size = ratio.length*size;
                    size = Math.ceil(size/16)*16;//16倍比例，最大尺寸128
                    if(size > 128)
                        size = 128;
                    param.scaleSizeX = size;
                }                            
                param.scaleSizeY = param.scaleSizeX;
                param.ratio = ratio;
            }
            return param;
        }
        public get fillRepeat():boolean
        {
            return this._fillRepeat;
        }
        public get fillGradientType():string
        {
            return this._fillGradientType;
        }
        public get lineGradientType():string
        {
            return this._lineGradientType;
        }
        public get miterLimit():number
        {
            return this._miterLimit;
        }

        public get thickness():number
        {
            return this._thickness;
        }
        public get cap():CanvasLineCap
        {
            return this._cap;
        }
        public get joint():CanvasLineJoin
        {
            return this._joint;
        }
        public get color():number[]
        {
            return this._color;
        }
        public get alpha():number[]
        {
            return this._alpha;
        }
        public get ratio():number[]
        {
            return this._ratio;
        }
        public get texture():egret.Texture
        {
            return this._texture;
        }
        public get lineMatrix():egret.Matrix
        {
            return this._lineMatrix;
        }
        public get fillMatrix():egret.Matrix
        {
            return this._fillMatrix;
        }
        public get fillColor():number[]
        {
            return this._fillColor;
        }
        public get fillAlpha():number[]
        {
            return this._fillAlpha;
        }
        public get fillRatio():number[]
        {
            return this._fillRatio;
        }
        public get fillTexture():egret.Texture
        {
            return this._fillTexture;
        }
        public getBatchTexture(tex:egret.Texture):egret.Texture
        {
            let s = this;
            let bTex:egret.Texture;
            if(s.isBatch())
            {
                let drawParam:BatchDrawParam = s._batchDrawParam;//记录原来的绘制参数，因为位图填充不需要graphics方式合批
                s.setBatchDrawParam(null);
                bTex = AtlasRender.getBatchTexture(tex, s);
                s.setBatchDrawParam(drawParam);
            }
            else
                bTex = tex;
            return bTex;
        }

        private static _tempPt0:egret.Point = new egret.Point;
        private static _tempPt1:egret.Point = new egret.Point;
        private static _tempPt2:egret.Point = new egret.Point;
        private static _tempPt3:egret.Point = new egret.Point;
        private static _tempMatrix:egret.Matrix = new egret.Matrix;

        protected _patternStyleMap:any;
        protected _batchDrawParam:BatchDrawParam;
        protected _smoothing:boolean;     
        protected _data:GraphicsData[];        

        protected _color:number[];
        protected _alpha:number[];
        protected _ratio:number[];
        protected _texture:egret.Texture;
        protected _lineMatrix:egret.Matrix;
        protected _cap:CanvasLineCap;
        protected _joint:CanvasLineJoin;
        protected _thickness:number;
        protected _miterLimit:number;

        protected _fillColor:number[];
        protected _fillAlpha:number[];
        protected _fillRatio:number[];
        protected _fillTexture:egret.Texture;
        protected _fillMatrix:egret.Matrix;
        protected _fillRepeat:boolean;
        protected _fillGradientType:string;
        protected _gradientMatrix:egret.Matrix;
        protected _densty:number;
        protected _lastLineNode:GYMeshNode;       
        protected _lastLineData:LineData; 
        protected _lineGradientType:string;
        protected _cacheDrawData:any[];
        protected _lastCapNodes:GYMeshNode[];
        protected _lastStartX:number;
        protected _lastStartY:number;
        protected _lastBezierNode:GYMeshNode;
        protected _isAllDraw:boolean;
        protected static _lineCaps:string[] = []
        // protected _lastJointNodes:GYMeshNode[];


        protected _batch: boolean;
        protected _batchAtlasName: string;
    }    
    
}
